package com.karaoke.android.player

import android.content.Context
import android.net.Uri
import android.view.Surface
import android.view.SurfaceHolder
import org.simple.eventbus.EventBus
import tv.danmaku.ijk.media.player.IMediaPlayer
import tv.danmaku.ijk.media.player.IjkMediaMeta
import tv.danmaku.ijk.media.player.IjkMediaPlayer
import tv.danmaku.ijk.media.player.MediaInfo
import tv.danmaku.ijk.media.player.misc.IMediaDataSource
import tv.danmaku.ijk.media.player.misc.ITrackInfo
import tv.danmaku.ijk.media.player.misc.IjkTrackInfo
import tv.danmaku.ijk.media.player.misc.IjkTrackInfo.MEDIA_TRACK_TYPE_AUDIO
import java.io.FileDescriptor
import java.util.*

/**
 * Created by Allen on 2016/10/24.
 */
class KHPlayer : IMediaPlayer
{
    override fun setOnTimedTextListener(p0: IMediaPlayer.OnTimedTextListener?)
    {
    }

    private val mPlayer: IjkMediaPlayer = IjkMediaPlayer()

    init
    {
        IjkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_SILENT)
        mPlayer.apply {
            setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 0)
            setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0)
            setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32.toLong())
            setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1)
            setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0)
            setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0)
            setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48)
            setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-hevc", 1)
            setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1)
        }
    }

    fun changeYuanBan(): YuanBan
    {
        when (audioChannel)
        {
            YuanBan.YC -> audioChannel = YuanBan.BC
            YuanBan.BC -> audioChannel = YuanBan.YC
            else       ->
            {
            }
        }
        EventBus.getDefault().post(YuanBanChangedEvent(audioChannel))
        return audioChannel
    }

    var audioChannel: YuanBan
        get()
        {
            var result = YuanBan.Unknown
            if (getAudioTracksCount() > 1)
            {
                val cur = getSelectAudioTrack()
                result = if (cur == 1) YuanBan.YC else YuanBan.BC
            }
            else
            {

            }

            return result
        }
        set(value)
        {
            if (getAudioTracksCount() > 1)
            {
                if (audioChannel != value)
                    when (value)
                    {
                        YuanBan.YC -> mPlayer.selectTrack(1)
                        YuanBan.BC -> mPlayer.selectTrack(2)
                        else       ->
                        {
                        }
                    }
                EventBus.getDefault().post(YuanBanChangedEvent(audioChannel))
            }
        }

    fun getAudioTracksCount(): Int
    {
        return getAudioTrackInfo()?.size ?: 0
    }

    fun getSelectAudioTrack(): Int
    {
        return mPlayer.getSelectedTrack(MEDIA_TRACK_TYPE_AUDIO)
    }

    private fun getAudioTrackInfo(): Array<ITrackInfo>?
    {
        val bundle = mPlayer.mediaMeta ?: return null
        val mediaMeta = IjkMediaMeta.parse(bundle)
        mediaMeta?.let {
            it.mStreams?.let {
                val trackInfos = ArrayList<IjkTrackInfo>()
                for (streamMeta in it)
                {
                    val trackInfo = IjkTrackInfo(streamMeta)
                    if (streamMeta.mType!!.equals(IjkMediaMeta.IJKM_VAL_TYPE__AUDIO, ignoreCase = true))
                    {
                        trackInfo.trackType = ITrackInfo.MEDIA_TRACK_TYPE_AUDIO
                    }
                    trackInfos.add(trackInfo)
                }
                return trackInfos.toTypedArray<ITrackInfo>()
            }
        }
        return null
    }

    /**
     * 单音轨声道
     */
    enum class Channel
    {
        Left,
        right,
        Stereo
    }

    enum class YuanBan
    {
        YC,
        BC,
        Unknown
    }

    override fun isPlayable(): Boolean = mPlayer.isPlayable

    override fun setOnInfoListener(p0: IMediaPlayer.OnInfoListener?) = mPlayer.setOnInfoListener(p0)

    override fun isLooping(): Boolean = mPlayer.isLooping

    override fun getDuration(): Long = mPlayer.duration

    override fun setOnCompletionListener(p0: IMediaPlayer.OnCompletionListener?) = mPlayer.setOnCompletionListener(p0)

    override fun seekTo(p0: Long) = mPlayer.seekTo(p0)


    override fun getDataSource(): String = mPlayer.dataSource

    override fun getCurrentPosition(): Long = mPlayer.currentPosition

    override fun setOnPreparedListener(p0: IMediaPlayer.OnPreparedListener?) = mPlayer.setOnPreparedListener(p0)

    override fun setDisplay(p0: SurfaceHolder?) = mPlayer.setDisplay(p0)

    override fun setOnVideoSizeChangedListener(p0: IMediaPlayer.OnVideoSizeChangedListener?) = mPlayer.setOnVideoSizeChangedListener(p0)

    override fun start()
    {
        mPlayer.start()
        EventBus.getDefault().post(this, "start")
    }

    override fun setVolume(p0: Float, p1: Float) = mPlayer.setVolume(p0, p1)

    override fun getVideoSarDen(): Int = mPlayer.videoSarDen

    override fun setLogEnabled(p0: Boolean) = mPlayer.setLogEnabled(p0)

    override fun getTrackInfo(): Array<out ITrackInfo> = mPlayer.trackInfo

    override fun setDataSource(p0: Context?, p1: Uri?) = mPlayer.setDataSource(p0, p1)

    override fun setDataSource(p0: Context?, p1: Uri?, p2: MutableMap<String, String>?) = mPlayer.setDataSource(p0, p1, p2)

    override fun setDataSource(p0: FileDescriptor?) = mPlayer.setDataSource(p0)

    override fun setDataSource(p0: String?)
    {
        mPlayer.dataSource = p0
    }

    override fun setDataSource(p0: IMediaDataSource?) = mPlayer.setDataSource(p0)

    override fun setKeepInBackground(p0: Boolean) = mPlayer.setKeepInBackground(p0)

    override fun reset() = mPlayer.reset()

    override fun setWakeMode(p0: Context?, p1: Int) = mPlayer.setWakeMode(p0, p1)

    override fun isPlaying(): Boolean = mPlayer.isPlaying

    override fun getMediaInfo(): MediaInfo = mPlayer.mediaInfo

    override fun setOnSeekCompleteListener(p0: IMediaPlayer.OnSeekCompleteListener?) = mPlayer.setOnSeekCompleteListener(p0)

    override fun pause()
    {
        mPlayer.pause()
        EventBus.getDefault().post(this, "pause")
    }

    override fun setOnErrorListener(p0: IMediaPlayer.OnErrorListener?) = mPlayer.setOnErrorListener(p0)

    override fun prepareAsync()
    {
        mPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1)
        mPlayer._prepareAsync()
    }

    override fun setAudioStreamType(p0: Int) = mPlayer.setAudioStreamType(p0)

    override fun getVideoWidth(): Int = mPlayer.videoWidth

    override fun setLooping(p0: Boolean)
    {
        mPlayer.isLooping = p0
    }

    override fun setScreenOnWhilePlaying(p0: Boolean)
    {
        mPlayer.setScreenOnWhilePlaying(p0)
    }

    override fun getVideoHeight(): Int = mPlayer.videoHeight

    override fun getVideoSarNum(): Int = mPlayer.videoSarNum

    override fun setSurface(p0: Surface?) = mPlayer.setSurface(p0)

    override fun stop() = mPlayer.stop()

    override fun setOnBufferingUpdateListener(p0: IMediaPlayer.OnBufferingUpdateListener?) = mPlayer.setOnBufferingUpdateListener(p0)

    override fun getAudioSessionId(): Int = mPlayer.audioSessionId

    override fun release() = mPlayer.release()


}